/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jobscheduling.model;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Serializable;

/**
 *
 * @author bursant
 */
public class Problem implements Comparable<Problem>, Serializable{
    private Job[] _jobs;
    private int _machines;
    private int _bestSolution;
    private String _name;
    private static int _nr = 1;
    
    @Override
    public boolean equals(Object o){
        return compareTo((Problem)o) == 0 ? true : false;
    }
    
    @Override
    public int compareTo(Problem o) {
        if (_machines != o._machines)
            return o._machines - _machines;
        if (_jobs.length != o._jobs.length)
            return o._jobs.length - _jobs.length;
            
        for (int i = 0; i < _jobs.length; ++i)
            for (int j = 0; j < _machines; ++j)
                if (_jobs[i].tasks[j] != o._jobs[i].tasks[j])
                    return o._jobs[i].tasks[j] - _jobs[i].tasks[j];
        return 0;
    }
    
    public void setBestSolution(int best){
        _bestSolution = best;
    }
    
    public int getBestSolution(){
        return _bestSolution;
    }
    
    public boolean equals(Problem o) {
        if (o._jobs.length != _jobs.length || o._machines != _machines)
            return false;
        
        for (int i = 0; i < _jobs.length; ++i)
            for (int j = 0; j < _jobs[i].tasks.length; j++)
                if (_jobs[i].tasks[j] != o._jobs[i].tasks[j])
                    return false;
        return true;
    }
    
    public Problem(){
        _jobs = new Job[0];
        _machines = 0;
        _name = "new" + Integer.toString(_nr);
        _nr++;
    }
    
    public Problem(Problem p){
        _jobs = p._jobs;
        _machines = p._machines;
        _name = p._name;
    }
    
    public Problem(BufferedReader reader, String fileName) throws IOException{
        String line = reader.readLine();

        _name = (fileName).replaceAll(".txt", "");

        _jobs = new Job[Integer.parseInt(line.split("\\s+")[1])];
        _bestSolution = Integer.parseInt(line.split("\\s+")[5]);
        _machines = Integer.parseInt(line.split("\\s+")[2]);

        for(int i = 0; i < _jobs.length; i++)
            _jobs[i] = new Job(i, _machines);
        line = reader.readLine();
        line = line.replaceFirst("$\\s+", "");
        for(int i = 0; i < _machines; i++){
            line = reader.readLine();
            String[] jobs = line.split("\\s+");
            for(int j = 0; j < _jobs.length; j++){    
                _jobs[j].tasks[i] = Integer.parseInt(jobs[j+1]);
            }
        } 
    }
    
    @Override
    public String toString(){
        return _name + " (machines: " + _machines + " jobs: " + _jobs.length + ")";
    }
    
    public int getMachinesNumber(){
        return _machines;
    }
    
    public void setMachinesNumber(int number){
        _machines = number;
        for (Job job : _jobs){
            job.setMachineNumber(number);
        }
    }
    
    public int[][] getRawJobs(){
        int[][] retval = new int[_machines][_jobs.length];
       
        for (int i = 0; i < _jobs.length; ++i){
            for (int j = 0; j < _jobs[i].tasks.length; ++j){
                retval[j][i] = _jobs[i].tasks[j];
            }
        }
        
        return retval;
    }
    
    public Job[] getJobs(){
        return _jobs;
    }
    
    public void setJobsNumber(int newJobsNumber){
        Job[] newJobs = new Job[newJobsNumber];
        int i = 0;
        while (i < newJobsNumber && i < _jobs.length){
            newJobs[i] = _jobs[i];
            i++;
        }
        while (i < newJobsNumber){
            newJobs[i] = new Job(i, _machines);
            i++;
        }
        _jobs = newJobs;
    }
    
    public void setJobs(Job[] jobs){
        _jobs = jobs;
    }
    
    public String getName(){
        return _name;
    }
    
    public void setName(String name){
        _name = name;
    }
    
    public void setTask(int jobIndex, int taskIndex, int duration){
        _jobs[jobIndex].tasks[taskIndex] = duration;
    }
}
